﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SalaDeEnsayo.WebApplication.SecurityAttributes;
using SalaDeEnsayo.ApplicationService.Model.Entity;
using SalaDeEnsayo.ApplicationService;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Text;
using System.Data;
using System.Collections;
using System.Reflection;
using SalaDeEnsayo.WebApplication.Pages.Helper;

namespace SalaDeEnsayo.WebApplication
{
    //[RolUsuario]
    //[RolAdminSistema]
    public partial class Reportes : System.Web.UI.Page
    {
        //1/1/1753 12:00:00 AM y 12/31/9999
        Hashtable htControls = new Hashtable();

        readonly DateTime dateMinValue = new DateTime(1753, 1, 1);
        readonly DateTime dateMaxValue = new DateTime(9999,12,31);

        private ReporteService reporteS;
        private static List<ReporteSalasReservadas> tableSalasReservadas;
        private static List<ReporteProductosVendidos> tableProdVendidos;
        private static List<ReporteRecaudacion> tableRecaudacion;

        public Reportes()
        {
            reporteS = new ReporteService();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            ((Web)this.Master).AddTrigger(this.btnExportToExcel);
            ((Web)this.Master).AddTrigger(this.btnExortarRptProdVendidos);
            ((Web)this.Master).AddTrigger(this.btnExportExcelRecaudacion);

            if (!IsPostBack)
            {
                LoadCombos();
                BindGridReports();
                BindGridProductosVendidos();
                BindGridRecaudacion();
            }
        }

        #region [ Metodos Privados ]

        private void LoadCombos()
        {
            SalaService salaS = new SalaService();
            List<Sala> listaSala = salaS.ObtenerSalas();

            GrupoService grupoS = new GrupoService();
            List<Grupo> listaGrupo = grupoS.GetAll();

            TipoProductoService tipoProductoS = new TipoProductoService();
            List<TipoProducto> listaTipoProducto = tipoProductoS.ObtenerTodos();

            ddlSalas.Items.Clear();
            ddlSalas.Items.Add(new ListItem("--Todos--", "0"));
            ddlSalas.Items.AddRange(listaSala.Select(s => new ListItem(s.Nombre, s.Id_Sala.ToString())).ToArray());

            ddlGrupos.Items.Clear();
            ddlGrupos.Items.Add(new ListItem("--Todos--", "0"));
            ddlGrupos.Items.AddRange(listaGrupo.Select(g => new ListItem(g.Nombre_grupo, g.Id.ToString())).ToArray());

            ddlTipo.Items.Clear();
            ddlTipo.Items.Add(new ListItem("--Todos--", "0"));
            ddlTipo.Items.AddRange(listaTipoProducto.Select(t => new ListItem(t.Descripcion, t.Id_Tipo.ToString())).ToArray());

            ddlProducto.Items.Clear();
            ddlProducto.Items.Add(new ListItem("--Todos--", "0"));
        }

        private void BindGridReports()
        {
            int? sala = ddlSalas.SelectedValue.Equals("0") ? (int?)null : Convert.ToInt32(ddlSalas.SelectedValue);
            long? grupo = ddlGrupos.SelectedValue.Equals("0") ? (long?)null : Convert.ToInt64(ddlGrupos.SelectedValue);
            DateTime? fecha_desde = txtFechaEntrada.Text == string.Empty ? dateMinValue : Convert.ToDateTime(txtFechaEntrada.Text);
            DateTime? fecha_hasta = txtFechaSalida.Text == string.Empty ? dateMaxValue : Convert.ToDateTime(txtFechaSalida.Text);

            try
            {
                tableSalasReservadas = reporteS.ObtenerSalasReservadas(fecha_desde, fecha_hasta, sala, grupo);
                grdReporte1.DataSource = tableSalasReservadas;
                grdReporte1.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void BindGridProductosVendidos()
        {
            int? tipo = ddlTipo.SelectedValue.Equals("0") ? (int?)null : Convert.ToInt32(ddlTipo.SelectedValue);
            long? producto = ddlProducto.SelectedValue.Equals("0") ? (long?)null : Convert.ToInt64(ddlProducto.SelectedValue);
            DateTime? fecha_desde = txtFechaDesdeProdVendidos.Text == string.Empty ? dateMinValue : Convert.ToDateTime(txtFechaDesdeProdVendidos.Text);
            DateTime? fecha_hasta = txtFechaHastaProdVendidos.Text == string.Empty ? dateMaxValue : Convert.ToDateTime(txtFechaHastaProdVendidos.Text);

            try
            {
                tableProdVendidos = reporteS.ObtenerProductosVendidos(fecha_desde, fecha_hasta, tipo, producto);
                grdProdVendidos.DataSource = tableProdVendidos;
                grdProdVendidos.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void BindGridRecaudacion()
        {
            DateTime? fecha_desde = txtFechaDesdeRecaudacion.Text == string.Empty ? dateMinValue : Convert.ToDateTime(txtFechaDesdeRecaudacion.Text);
            DateTime? fecha_hasta = txtFechaHastaRecaudacion.Text == string.Empty ? dateMaxValue : Convert.ToDateTime(txtFechaHastaRecaudacion.Text);

            try
            {
                tableRecaudacion = reporteS.ObtenerRecaudacion(fecha_desde, fecha_hasta);
                grdReporteRecaudacion.DataSource = tableRecaudacion;
                grdReporteRecaudacion.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void BindGridExcelSalas()
        {
            try
            {
                grdExcel.DataSource = tableSalasReservadas;
                grdExcel.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void BindGridExcel()
        {
            try
            {
                grdExcel.DataSource = tableProdVendidos;
                grdExcel.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void BindGridExcelRecaudacion()
        {
            try
            {
                grdExcel.DataSource = tableRecaudacion;
                grdExcel.DataBind();
            }
            catch (Exception ex)
            {
                Master.ShowAlert("Ocurrió un problema inesperado, por favor intente mas tarde.");
            }
        }

        private void PrepareGridViewForExport(Control gv)
        {
            Literal l = new Literal();
            for (int i = 0; i < gv.Controls.Count; i++)
            {
                if ((null != htControls[gv.Controls[i].GetType().Name]) || (null != htControls[gv.Controls[i].GetType
                   ().BaseType.Name]))
                {
                    l.Text = GetControlPropertyValue(gv.Controls[i]);
                    gv.Controls.Remove(gv.Controls[i]);
                    gv.Controls.AddAt(i, l);
                }
                if (gv.Controls[i].HasControls())
                {
                    PrepareGridViewForExport(gv.Controls[i]);
                }
            }
        }

        private string GetControlPropertyValue(Control control)
        {
            Type controlType = control.GetType();
            string strControlType = controlType.Name;
            string strReturn = "Error";
            bool bReturn;

            PropertyInfo[] ctrlProps = controlType.GetProperties();
            string ExcelPropertyName = (string)htControls[strControlType];
            if (ExcelPropertyName == null)
            {
                ExcelPropertyName = (string)htControls[control.GetType().BaseType.Name];
                if (ExcelPropertyName == null)
                    return strReturn;
            }
            foreach (PropertyInfo ctrlProp in ctrlProps)
            {
                if (ctrlProp.Name == ExcelPropertyName &&
                ctrlProp.PropertyType == typeof(String))
                {
                    try
                    {
                        strReturn = (string)ctrlProp.GetValue(control, null);
                        break;
                    }
                    catch
                    {
                        strReturn = "";
                    }
                }
                if (ctrlProp.Name == ExcelPropertyName &&
                ctrlProp.PropertyType == typeof(bool))
                {
                    try
                    {
                        bReturn = (bool)ctrlProp.GetValue(control, null);
                        strReturn = bReturn ? "True" : "False";
                        break;
                    }
                    catch
                    {
                        strReturn = "Error";
                    }
                }

                if (ctrlProp.Name == ExcelPropertyName &&
                ctrlProp.PropertyType == typeof(ListItem))
                {
                    try
                    {
                        strReturn = ((ListItem)(ctrlProp.GetValue(control, null))).Text;
                        break;
                    }
                    catch
                    {
                        strReturn = "";
                    }
                }
            }
            return strReturn;
        }

        private void DoExportGridView(GridView grid, string fileName)
        {
            DataTable DT = new DataTable();

            for (int i = 0; i < grid.Columns.Count; i++)
                DT.Columns.Add(grid.Columns[i].HeaderText);

            foreach (GridViewRow row in this.grdExcel.Rows)
            {
                DataRow fila = DT.NewRow();
                for (int j = 0; j < row.Cells.Count; j++)
                    fila[j] = row.Cells[j].Text == "&nbsp;" || row.Cells[j].Text == string.Empty ? "" : row.Cells[j].Text;

                DT.Rows.Add(fila);
            }

            ExportToExcel.ToExcel(DT, fileName, Page.Response);

        }

        #endregion

        #region [ Eventos ]

        protected void btnBuscar_Click(object sender, EventArgs e)
        {
            BindGridReports();
        }

        protected void btnBuscarRptProdVendidos_Click(object sender, EventArgs e)
        {
            BindGridProductosVendidos();
        }

        protected void btnSearch_Click(object sender, EventArgs e)
        {
            BindGridRecaudacion();
        }

        protected void grdReporte1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            grdReporte1.PageIndex = e.NewPageIndex;
            BindGridReports();
        }

        protected void grdProdVendidos_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            grdProdVendidos.PageIndex = e.NewPageIndex;
            BindGridProductosVendidos();
        }

        protected void grdReporteRecaudacion_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            grdReporteRecaudacion.PageIndex = e.NewPageIndex;
            BindGridRecaudacion();
        }

        protected void btnExportToExcel_Click(object sender, ImageClickEventArgs e)
        {
            BindGridExcelSalas();
            PrepareGridViewForExport(grdExcel);
            DoExportGridView(this.grdReporte1, "Reporte_Salas_Reservadas.xls");
        }

        protected void btnExortarRptProdVendidos_Click(object sender, ImageClickEventArgs e)
        {
            BindGridExcel();
            PrepareGridViewForExport(grdExcel);
            DoExportGridView(this.grdProdVendidos, "Reporte_Prod_Vendidos.xls");
        }

        protected void btnExportExcelRecaudacion_Click(object sender, ImageClickEventArgs e)
        {
            BindGridExcelRecaudacion();
            PrepareGridViewForExport(grdExcel);
            DoExportGridView(this.grdReporteRecaudacion, "Reporte_Recaudacion.xls");
        }

        public override void VerifyRenderingInServerForm(Control control) { }

        protected void ddlTipo_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProductoService productoS = new ProductoService();
            List<Producto> listaProducto = productoS.ObtenerPorIdTipo(int.Parse(ddlTipo.SelectedValue));

            ddlProducto.Items.Clear();
            ddlProducto.Items.Add(new ListItem("--Todos--", "0"));
            ddlProducto.Items.AddRange(listaProducto.Select(p => new ListItem(p.Descripcion, p.Id_Producto.ToString())).ToArray());
        }

        #endregion
    }
}
